using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Zune.Forms
{
    /// <summary>
    /// A Zune.Form Button control.
    /// </summary>
    public class Button : Control
    {
        #region Public Events
        #endregion

        #region Private Members
        private string _text = "Button";
        private string _bgImage;
        private string _bgImagePressed;
        private Texture2D _backgroundImage;
        private Texture2D _backgroundImagePressed;
        private Texture2D _vLine;
        private Texture2D _hLine;
        private SpriteFont _font;
        private Color _borderColor = Color.Black;
        private Color _foreShadowColor = Color.LightGray;
        private Color _pressedShadowColor = Color.LightGray;
        private Color _pressedBackgroundColor = Color.DarkGray;
        private Color _pressedForeColor = Color.White;
        private int _borderWidth = 2;
        private bool _isPressed = false;
        //private bool _displayBorder = true;
        private bool _textDropShadow = false;
        private bool _autoSizeToImage = true;
        
        #endregion

        #region Constructors
        /// <summary>
        /// A Button control.
        /// </summary>
        /// <param name="form">The Form control the Button will placed on.</param>
        public Button(Form form) : base(form)
        {
            base.Location = new Vector2(10, 10);
            base.Size = new Vector2(100, 50);
            base.BackColor = Color.LightGray;
            base.ForeColor = Color.White;
            base.BorderType = Enumerations.BorderType.BorderSingle;
        }

        public Button(Control parent) : base(parent)
        {
            base.Location = new Vector2(10, 10);
            base.Size = new Vector2(100, 50);
            base.BackColor = Color.LightGray;
            base.ForeColor = Color.White;
            base.BorderType = Enumerations.BorderType.BorderSingle;
        }
        #endregion

        #region Public Overrides
        public override void LoadContent()
        {
            if (!string.IsNullOrEmpty(_bgImage))
            {
                _backgroundImage = base.Form.Content.Load<Texture2D>(_bgImage);
                if (_autoSizeToImage)
                    base.Size = new Vector2(_backgroundImage.Width, _backgroundImage.Height);
            }
            if (!string.IsNullOrEmpty(_bgImagePressed))
            {
                _backgroundImagePressed = base.Form.Content.Load<Texture2D>(_bgImagePressed);
            }
            _font = base.Form.Content.Load<SpriteFont>("DefaultFont");
            //_hLine = Drawing.CreateLine(base.GraphicsDevice, 0, 0, (Int32)base.Size.X, _borderWidth, _borderColor);
            //_vLine = Drawing.CreateLine(base.GraphicsDevice, 0, 0, _borderWidth, (Int32)base.Size.Y, _borderColor);
            base.LoadContent();
        }

        public override void Draw(GameTime gameTime)
        {
            if (base.Visible)
            {
                Vector2 textSize = _font.MeasureString(_text);

                if (_backgroundImage != null)
                {
                    if (!_isPressed)
                    {
                        base.SpriteBatch.Draw(_backgroundImage, new Rectangle((Int32)base.Location.X, (Int32)base.Location.Y, (Int32)base.Size.X, (Int32)base.Size.Y), Color.White);
                    }
                }
                else
                {
                    Texture2D background = Drawing.CreateRectangle(base.GraphicsDevice, (Int32)base.Size.X, (Int32)base.Size.Y, _backColor);
                    base.SpriteBatch.Draw(background, base.Location, Color.White);
                }

                if (_isPressed)
                {
                    if (_backgroundImagePressed != null)
                    {
                        base.SpriteBatch.Draw(_backgroundImagePressed, new Rectangle((Int32)base.Location.X, (Int32)base.Location.Y, (Int32)base.Size.X, (Int32)base.Size.Y), _foreColor);
                    }
                    else
                    {
                        Texture2D pressed = Drawing.CreateRectangle(base.GraphicsDevice, (Int32)base.Size.X, (Int32)base.Size.Y, _pressedBackgroundColor);
                        base.SpriteBatch.Draw(pressed, base.Location, _pressedForeColor);
                    }
                }

                //if (_displayBorder)
                //{
                //    base.SpriteBatch.Draw(_hLine, new Vector2(base.Location.X, base.Location.Y), Color.White);
                //    base.SpriteBatch.Draw(_hLine, new Vector2(base.Location.X, base.Location.Y + base.Size.Y - _borderWidth), Color.White);
                //    base.SpriteBatch.Draw(_vLine, new Vector2(base.Location.X, base.Location.Y), Color.White);
                //    base.SpriteBatch.Draw(_vLine, new Vector2(base.Location.X + base.Size.X - _borderWidth, _location.Y), Color.White);
                //}

                Vector2 textLocation = new Vector2(base.Location.X + (base.Size.X / 2) - (textSize.X / 2), base.Location.Y + (base.Size.Y / 2) - (textSize.Y / 2));

                if (_textDropShadow)
                {
                    if (_isPressed)
                    {
                        Drawing.DrawShadowedString(base.SpriteBatch, _font, _text, textLocation, _pressedForeColor, _pressedShadowColor);
                    }
                    else
                    {
                        Drawing.DrawShadowedString(base.SpriteBatch, _font, _text, textLocation, _foreColor, _foreShadowColor);
                    }
                }
                else
                {
                    if (_isPressed)
                    {
                        base.SpriteBatch.DrawString(_font, _text, textLocation, _pressedForeColor);
                    }
                    else
                    {
                        base.SpriteBatch.DrawString(_font, _text, textLocation, _foreColor);
                    }
                }


                //if (_isPressed)
                //{
                //    base.GraphicsDevice.Clear(_pressedBackgroundColor);
                //}
                //else
                //{
                //    base.GraphicsDevice.Clear(base.BackColor);
                //}
                if (_backgroundImage == null)
                    base.Draw(gameTime);
            }
        }

        public override void Update(GameTime gameTime, TouchCollection touches)
        {
            if (base.Visible && base.Enabled)
            {
                if (touches.Count > 0)
                {
                    TouchLocation touch = touches[0];
                    if (Utilities.IsControlClicked(touch, _location, _size))
                    {
                        switch (touch.State)
                        {
                            case TouchLocationState.Moved:
                            case TouchLocationState.Pressed:
                                _isPressed = true;
                                break;
                            case TouchLocationState.Released:
                                _isPressed = false;
                                break;
                        }
                    }
                    else
                    {
                        _isPressed = false;
                    }
                }
                else
                {
                    _isPressed = false;
                }

                base.Update(gameTime, touches);
            }
        }
        #endregion

        #region Public Properties
        /// <summary>
        /// Gets or sets the BackGround Color when the Button is in its pressed state.
        /// </summary>
        public Color PressedBackGroundColor
        {
            get { return _pressedBackgroundColor; }
            set { _pressedBackgroundColor = value; }
        }

        /// <summary>
        /// Gets or sets the ForeColor when the Button is in its pressed state.
        /// </summary>
        public Color PressedForeColor
        {
            get { return _pressedForeColor; }
            set { _pressedForeColor = value; }
        }

        /// <summary>
        /// Gets or sets whether a shadow will be shown for the text.
        /// </summary>
        public bool ShowTextShadow
        {
            get { return _textDropShadow; }
            set { _textDropShadow = value; }
        }

        /// <summary>
        /// Gets or sets the Color of the shadow.
        /// </summary>
        public Color ForeShadowColor
        {
            get { return _foreShadowColor; }
            set { _foreShadowColor = value; }
        }

        /// <summary>
        /// Gets or sets the name of an image (Must exist in the Content folder) to use for the Background.
        /// </summary>
        public string BackgroundImage
        {
            get { return _bgImage; }
            set { _bgImage = value; }
        }

        /// <summary>
        /// Gets or sets the name of an image (Must exist in the Content folder) to use for the Background
        /// when the Button is in its pressed state.
        /// </summary>
        public string BackgroundImagePressed
        {
            get { return _bgImagePressed; }
            set { _bgImagePressed = value; }
        }

        /// <summary>
        /// Gets or sets the Text.
        /// </summary>
        public string Text
        {
            get { return _text; }
            set { _text = value; }
        }

        /// <summary>
        /// Gets or sets the Color to be used as the border.
        /// </summary>
        public Color BorderColor
        {
            get { return _borderColor; }
            set { _borderColor = value; }
        }

        /// <summary>
        /// Gets or sets the width of the border.
        /// </summary>
        public int BorderWidth
        {
            get { return _borderWidth; }
            set { _borderWidth = value; }
        }
        #endregion
    }
}